using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace MKDS_Course_Editor
{
    public partial class nds_rom : Form
    {
        
        public int ncgr;
        public int nclr;
        public int nscr;
        public int narn;
        public int ncer;
        Players.MusicPlayer m;
        private Dictionary<int, TreeNode> DirHolder;
        NitroExplorer.NitroClass nc = new NitroExplorer.NitroClass();
        string file_;
        public nds_rom(string file, Form1 f1, Players.MusicPlayer m)
        {
            nc.ROMIsReady += ROM_ROMIsReady;
            nc.DirReady += ROM_DirReady;
            nc.FileReady += ROM_FileReady;
            Form1 f = new Form1();
            InitializeComponent();
            treeView1.ImageList = f.imageList1;
            file_ = file;
            this.m = m;
        }
        private void ParseNode(TreeNode node)
        {
            if (node.Text.Contains(".") && node.Nodes.Count == 0)
            {
                node.ContextMenuStrip = contextMenuStrip2;
                switch (Path.GetExtension(node.Text).ToLower())
                {
                    case ".nsbtx":
                        node.ImageIndex = 1;
                        node.SelectedImageIndex = 1;
                        break;
                    case ".nsbmd":
                        node.ImageIndex = 2;
                        node.SelectedImageIndex = 2;
                        break;
                    case ".nsbtp":
                    case ".nsbta":
                        node.ImageIndex = 4;
                        node.SelectedImageIndex = 4;
                        break;
                    case ".nkm":
                        node.ImageIndex = 5;
                        node.SelectedImageIndex = 5;
                        break;
                    case ".kcl":
                        node.ImageIndex = 6;
                        node.SelectedImageIndex = 6;
                        break;
                    case ".nclr":
                        node.ImageIndex = 7;
                        node.SelectedImageIndex = 7;
                        break;
                    case ".ncgr":
                        node.ImageIndex = 8;
                        node.SelectedImageIndex = 8;
                        break;
                    case ".nscr":
                        node.ImageIndex = 9;
                        node.SelectedImageIndex = 9;
                        break;
                    case ".ncer":
                        node.ImageIndex = 10;
                        node.SelectedImageIndex = 10;
                        break;
                    case ".nanr":
                        node.ImageIndex = 11;
                        node.SelectedImageIndex = 11;
                        break;
                    case ".narc":
                        node.ImageIndex = 12;
                        node.SelectedImageIndex = 12;
                        node.ContextMenuStrip = contextMenuStrip1;
                        break;
                    case ".carc":
                        node.ImageIndex = 13;
                        node.SelectedImageIndex = 13;
                        node.ContextMenuStrip = contextMenuStrip1;
                        break;
                    case ".sdat":
                        node.ImageIndex = 14;
                        node.SelectedImageIndex = 14;
                        break;
                    default:
                        node.ImageIndex = 0;
                        node.SelectedImageIndex = 0;
                        break;
                }
            }
            else
            {
                node.ImageIndex = 3;
                node.SelectedImageIndex = 3;
            }
            foreach (TreeNode child in node.Nodes)
                ParseNode(child);

            //TODO: work goes here for DFS 
        }
        private void nds_rom_Load(object sender, EventArgs e)
        {
            this.treeView1.Nodes.Clear();
            this.DirHolder = new Dictionary<int, TreeNode>();
            nc.LoadROM(file_);
        }
        private void ROM_ROMIsReady(long TimeTakenMS)
        {
            this.DirHolder[0xf000].Expand();
            foreach (TreeNode rootNode in treeView1.Nodes)
            {
                ParseNode(rootNode);
            }
            Romer.NdsIcon n = new Romer.NdsIcon();
            n.NdsFile = file_;
            n.GetBounds();
            n.GetPallete();
            n.GetTile();
            Color[] c = new Color[16];
            Bitmap b = n.GetIcon(out c);
            //b.MakeTransparent(c[0]);
            pictureBox1.Image = b;
            listView1.Items[0].SubItems[1].Text = n.GetTitle(1).Split((char)0x0A)[0].Replace(Convert.ToString('\0'),"");
            try
            {
                listView1.Items[1].SubItems[1].Text = n.GetTitle(1).Split((char)0x0A)[1].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            try
            {
                listView1.Items[2].SubItems[1].Text = n.GetTitle(1).Split((char)0x0A)[2].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            listView1.Items[5].SubItems[1].Text = n.GetTitle(2).Split((char)0x0A)[0].Replace(Convert.ToString('\0'), "");
            try
            {
                listView1.Items[6].SubItems[1].Text = n.GetTitle(2).Split((char)0x0A)[1].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            try
            {
                listView1.Items[7].SubItems[1].Text = n.GetTitle(2).Split((char)0x0A)[2].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            listView1.Items[8].SubItems[1].Text = n.GetTitle(3).Split((char)0x0A)[0].Replace(Convert.ToString('\0'), "");
            try
            {
                listView1.Items[9].SubItems[1].Text = n.GetTitle(3).Split((char)0x0A)[1].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            try
            {
                listView1.Items[10].SubItems[1].Text = n.GetTitle(3).Split((char)0x0A)[2].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            listView1.Items[11].SubItems[1].Text = n.GetTitle(4).Split((char)0x0A)[0].Replace(Convert.ToString('\0'), "");
            try
            {
                listView1.Items[12].SubItems[1].Text = n.GetTitle(4).Split((char)0x0A)[1].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            try
            {
                listView1.Items[13].SubItems[1].Text = n.GetTitle(4).Split((char)0x0A)[2].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            listView1.Items[14].SubItems[1].Text = n.GetTitle(5).Split((char)0x0A)[0].Replace(Convert.ToString('\0'), "");
            try
            {
                listView1.Items[15].SubItems[1].Text = n.GetTitle(5).Split((char)0x0A)[1].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            try
            {
                listView1.Items[16].SubItems[1].Text = n.GetTitle(5).Split((char)0x0A)[2].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            listView1.Items[17].SubItems[1].Text = n.GetTitle(6).Split((char)0x0A)[0].Replace(Convert.ToString('\0'), "");
            try
            {
                listView1.Items[18].SubItems[1].Text = n.GetTitle(6).Split((char)0x0A)[1].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            try
            {
                listView1.Items[19].SubItems[1].Text = n.GetTitle(6).Split((char)0x0A)[2].Replace(Convert.ToString('\0'), "");
            }
            catch { }
            listView1.Items[3].SubItems[1].Text = n.GetROMTitle().Replace(Convert.ToString('\0'), ""); 
            listView1.Items[4].SubItems[1].Text = n.GetCountryCode();
        }
        private void ROM_DirReady(int DirID, int ParentID, string DirName, bool IsRoot)
        {
            if (IsRoot)
            {
                this.DirHolder[0xf000] = this.treeView1.Nodes.Add("61440", "Root [" + file_.Substring(file_.LastIndexOf('\\') + 1) + "]", 0, 0);
                this.DirHolder[0xf000].Tag = "61440";
            }
            else
            {
                this.DirHolder[DirID] = this.DirHolder[ParentID].Nodes.Add(DirID.ToString(), DirName, 0, 0);
                this.DirHolder[DirID].Tag = DirID.ToString();
            }
            foreach (TreeNode rootNode in treeView1.Nodes)
                ParseNode(rootNode);
        }
        private void ROM_FileReady(int FileID, int ParentID, string FileName)
        {
            this.DirHolder[ParentID].Nodes.Add(FileID.ToString(), FileName, 2, 2).Tag = FileID.ToString();
            foreach (TreeNode rootNode in treeView1.Nodes)
                ParseNode(rootNode);
        }
        private void tvFiles_AfterSelect(object sender, TreeViewEventArgs e)
        {
            string str;
            ushort num = Convert.ToUInt16(e.Node.Tag);
            if (num >= 0xf000)
            {
                str = string.Concat(new object[] { "Directory: ", e.Node.Text, " - ID ", e.Node.Tag });
                //this.extractButton.Enabled = false;
                //this.reinsertButton.Enabled = false;
            }
            else
            {
                object[] objArray2 = new object[] { "Offset: 0x", this.nc.FileOffsets[num].ToString("X"), " - Size: ", this.nc.FileSizes[num].ToString(), " bytes - ID ", e.Node.Tag };
                str = string.Concat(objArray2);
                //this.extractButton.Enabled = true;
                //this.reinsertButton.Enabled = true;
            }
            //this.toolStripStatusLabel1.Text = str;
        }

        private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {

            Form1 f = (Form1)Form1.FromHandle(this.Owner.Handle);
            switch (Path.GetExtension(e.Node.Text).ToLower())
            {
                case ".bmg":
                    bmg b = new bmg(nc.ExtractFile(Convert.ToUInt16(e.Node.Name)));
                    b.ShowDialog();
                    nc.ReplaceFile(Convert.ToUInt16(e.Node.Name), b.file_);
                    break;
                case ".nsbmd":
                    bool found = false;
                    for (int i = 0; i < e.Node.Parent.Nodes.Count; i++)
                    {
                        if (e.Node.Parent.Nodes[i].Text == e.Node.Text.Replace(".nsbmd", ".nsbtx"))
                        {
                            found = true;
                            Form ns = new nsbmd(nc.ExtractFile(Convert.ToUInt16(e.Node.Name)), nc.ExtractFile(Convert.ToUInt16(e.Node.Parent.Nodes[i].Name)));
                            ns.ShowDialog();
                            break;
                        }
                    }
                    if (found == false)
                    {
                        Form ns = new nsbmd(nc.ExtractFile(Convert.ToUInt16(e.Node.Name)));
                        ns.ShowDialog();
                    }
                    break;
                case ".nclr":
                    nclr = Convert.ToInt32(e.Node.Name);
                    f.doAction(nc.ExtractFile((ushort)nclr), e.Node.Text, (ushort)nclr);
                    break;
                case ".ncgr":
                    ncgr = Convert.ToInt32(e.Node.Name);
                    if (nclr != null && ncgr != null)
                    {
                        f.doAction(nc.ExtractFile((ushort)ncgr), nc.ExtractFile((ushort)nclr), e.Node.Text, nc.FileNames[(ushort)nclr]);
                    }
                    break;
                case ".carc":
                    f.doAction(nc.ExtractFile(Convert.ToUInt16(e.Node.Name)), e.Node.Text, Convert.ToUInt16(e.Node.Name));
                    break;
                case ".bmd":
                    //Form bm = new bmd_view(nc.ExtractFile(Convert.ToUInt16(e.Node.Name)), e.Node.Text);
                    //bm.ShowDialog();
                    break;
                case ".narc":
                    f.doAction(nc.ExtractFile(Convert.ToUInt16(e.Node.Name)), e.Node.Text, Convert.ToUInt16(e.Node.Name));
                    break;
                case ".ncer":
                    ncer = Convert.ToInt32(e.Node.Name);
                    if (nclr != null && ncgr != null && ncer != null)
                    {
                        f.doAction(nc.ExtractFile((ushort)ncer), nc.ExtractFile((ushort)ncgr), nc.ExtractFile((ushort)nclr), e.Node.Text, nc.FileNames[(ushort)ncgr], nc.FileNames[(ushort)nclr]);
                    }
                    break;
                case ".nanr":
                    narn = Convert.ToInt32(e.Node.Name);
                    if (nclr != null && ncgr != null && narn != null && ncer != null)
                    {
                        f.doAction(nc.ExtractFile((ushort)narn), nc.ExtractFile((ushort)ncer), nc.ExtractFile((ushort)ncgr), nc.ExtractFile((ushort)nclr), e.Node.Text, nc.FileNames[(ushort)ncer], nc.FileNames[(ushort)ncgr], nc.FileNames[(ushort)nclr]);
                    }
                    break;
                case ".sdat":
                    Form s = new sdat_(nc.ExtractFile(Convert.ToUInt16(e.Node.Name)), e.Node.Text, m);
                    s.ShowDialog();
                    break;
                case ".swav":
                    Form s2 = new swav(nc.ExtractFile(Convert.ToUInt16(e.Node.Name)), e.Node.Text);
                    s2.ShowDialog();
                    break;
                case ".nscr":
                    nscr = Convert.ToInt32(e.Node.Name);
                    if (nclr != null && ncgr != null && nscr != null)
                    {
                        f.doAction(nc.ExtractFile((ushort)nscr), nc.ExtractFile((ushort)ncgr), nc.ExtractFile((ushort)nclr), e.Node.Text, nc.FileNames[(ushort)ncgr], nc.FileNames[(ushort)nclr]);
                    }
                    break;
            }

        }

        private void openAsSecondToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form1 f = (Form1)Form1.FromHandle(this.Owner.Handle);
            f.doAction(nc.ExtractFile(Convert.ToUInt16(treeView1.SelectedNode.Name)), treeView1.SelectedNode.Text, true, Convert.ToUInt16(treeView1.SelectedNode.Name));
        }

        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                treeView1.SelectedNode = e.Node;
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form1 f = (Form1)Form1.FromHandle(this.Owner.Handle);
            f.doAction(nc.ExtractFile(Convert.ToUInt16(treeView1.SelectedNode.Name)), treeView1.SelectedNode.Text, Convert.ToUInt16(treeView1.SelectedNode.Name));
        }

        private void exportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog1.FileName = treeView1.SelectedNode.Text;
            if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK
                && saveFileDialog1.FileName.Length > 0)
            {
                File.WriteAllBytes(saveFileDialog1.FileName, nc.ExtractFile(Convert.ToUInt16(treeView1.SelectedNode.Name)));
            }
        }

        private void replaceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.FileName = treeView1.SelectedNode.Text;
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK
                && openFileDialog1.FileName.Length > 0)
            {
                nc.ReplaceFile(Convert.ToUInt16(treeView1.SelectedNode.Name), File.ReadAllBytes(openFileDialog1.FileName));
            }
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            saveFileDialog1.FileName = treeView1.SelectedNode.Text;
            if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK
                && saveFileDialog1.FileName.Length > 0)
            {
                File.WriteAllBytes(saveFileDialog1.FileName, nc.ExtractFile(Convert.ToUInt16(treeView1.SelectedNode.Name)));
            }
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            openFileDialog1.FileName = treeView1.SelectedNode.Text;
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK
                && openFileDialog1.FileName.Length > 0)
            {
                nc.ReplaceFile(Convert.ToUInt16(treeView1.SelectedNode.Name), File.ReadAllBytes(openFileDialog1.FileName));
            }
        }

        public string getName(short ID)
        {
            return nc.FileNames[(ushort)ID];
        }
        public void replace(short ID, byte[] file)
        {
            nc.ReplaceFile((ushort)ID, file);
        }
    }
}
